home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / sgf2mi13.taz / sgf2mi13 / gorules.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-27  |  5.2 KB  |  234 lines

  1. /* #[info:            */
  2. /************************************************************************
  3.  *                                    *
  4.  *             ####   ####  ####   #     # #      #####  ####           *
  5.  *            #      #    # #   #  #     # #      #     #               *
  6.  *            #      #    # #  #   #     # #      #     #               *
  7.  *            #  ##  #    # ###    #     # #      ###    ###            *
  8.  *            #    # #    # #  #   #     # #      #         #           *
  9.  *            #    # #    # #   #  #     # #      #         #           *
  10.  *             ####   ####  #    # ####### ###### ##### ####            *
  11.  *                                    *
  12.  *                Jan van der Steen                *
  13.  *                                    *
  14.  *          Centre for Mathematics and Computer Science        *
  15.  *              Amsterdam, the Netherlands            *
  16.  *                                    *
  17.  *----------------------------------------------------------------------*
  18.  * File   : gorules.c                         *
  19.  * Purpose : Implement the Japanese Go Rules                *
  20.  * Version : 1.2                        *
  21.  * Modified: 2/12/93 16:41:25                        *
  22.  * Author  : Jan van der Steen (jansteen@cwi.nl)            *
  23.  ************************************************************************/
  24. /* #]info:            */ 
  25. /* #[include:            */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include "tools.h"
  31. #include "gogame.h"
  32. #include "gorules.h"
  33.  
  34. /* #]include:            */ 
  35. /* #[static:            */
  36.  
  37. static int    theside  = 0;
  38. static int    thelibs  = 0;
  39.  
  40. /* #]static:            */ 
  41. /* #[prototype:         */
  42.  
  43. #ifdef __STDC__
  44. #    define    PROTO(s) s
  45. #else
  46. #    define    PROTO(s) ()
  47. #endif
  48.  
  49. static int    goban_loop    PROTO(( GOGAME *gogame,
  50.                     GONODE *gonode,
  51.                     int (*f)PROTO(( GOGAME *gogame,
  52.                             GONODE *gonode))));
  53. static int    goban_do    PROTO(( GOGAME *gogame,
  54.                     GONODE *gonode,
  55.                     int (*f)PROTO(( GOGAME *gogame,
  56.                             GONODE *gonode))));
  57. static int    rules_liberty    PROTO((    GOGAME *gogame, GONODE *gonode));
  58. static int    rules_remove    PROTO((    GOGAME *gogame, GONODE *gonode));
  59.  
  60. #undef PROTO
  61.  
  62. /* #]prototype:         */ 
  63.  
  64. /* #[goban_loop:        */
  65.  
  66. #ifdef __STDC__
  67. #    define    PROTO(s) s
  68. #else
  69. #    define    PROTO(s) ()
  70. #endif
  71.  
  72. static int
  73. goban_loop(gogame, gonode, f)
  74. /*
  75.  * Visit "all" goban points and execute f()
  76.  */
  77. GOGAME *gogame;
  78. GONODE *gonode;
  79. int    (*f)PROTO((GOGAME *gogame, GONODE *gonode));
  80. {
  81.     (gogame->gm_goban->gb_loop)++;
  82.  
  83.     return goban_do(gogame, gonode, f);
  84. }
  85.  
  86. #undef PROTO
  87.  
  88. /* #]goban_loop:        */ 
  89. /* #[goban_do:            */
  90.  
  91. #ifdef __STDC__
  92. #    define    PROTO(s) s
  93. #else
  94. #    define    PROTO(s) ()
  95. #endif
  96.  
  97. static int
  98. goban_do(gogame, gonode, f)
  99. /*
  100.  * Visit "all" goban points and execute f()
  101.  */
  102. GOGAME *gogame;
  103. GONODE *gonode;
  104. int    (*f)PROTO((GOGAME *gogame, GONODE *gonode));
  105. {
  106.     /*
  107.      * On the goban?
  108.      */
  109.     if (gonode == (GONODE *) 0) return 0;
  110.  
  111.     /*
  112.      * First time?
  113.      */
  114.     if (gonode->gn_loop == gogame->gm_goban->gb_loop) return 0;
  115.  
  116.     /*
  117.      * Mark goban point
  118.      */
  119.     gonode->gn_loop = gogame->gm_goban->gb_loop;
  120.  
  121.     if (! (*f)(gogame, gonode)) return 0;
  122.  
  123.     return (
  124.     goban_do(gogame, gonode->gn_n, f) +
  125.     goban_do(gogame, gonode->gn_e, f) +
  126.     goban_do(gogame, gonode->gn_s, f) +
  127.     goban_do(gogame, gonode->gn_w, f));
  128. }
  129.  
  130. #undef PROTO
  131.  
  132. /* #]goban_do:            */ 
  133. /* #[rules_liberty:        */
  134.  
  135. static int
  136. rules_liberty(gogame, gonode)
  137. /*
  138.  * Calculate the liberties of a chain
  139.  */
  140. GOGAME *gogame;
  141. GONODE *gonode;
  142. {
  143.     if (gonode->gn_stone == (GOMOVE *) 0) {
  144.     /*
  145.      * Update liberties
  146.      */
  147.     thelibs++;
  148.     return 0;
  149.     }
  150.     return (gonode->gn_stone->mv_side == theside);
  151. }
  152.  
  153. /* #]rules_liberty:        */ 
  154. /* #[rules_remove:        */
  155.  
  156. static int
  157. rules_remove(gogame, gonode)
  158. /*
  159.  * Remove the members of a chain
  160.  */
  161. GOGAME *gogame;
  162. GONODE *gonode;
  163. {
  164.     if (gonode->gn_stone == (GOMOVE *) 0) return 0;
  165.     if (gonode->gn_stone->mv_side == theside) {
  166.     /*
  167.      * Remove stone from the board
  168.      */
  169.     capture_store(gogame, gonode);
  170.     gonode->gn_stone = (GOMOVE *) 0;
  171.     return 1;
  172.     }
  173.     return 0;
  174. }
  175.  
  176. /* #]rules_remove:        */ 
  177. /* #[rules_check:        */
  178.  
  179. int
  180. rules_check(gogame, place, side)
  181. /*
  182.  * Check whether a stone in "gogame" from "side" at "place" is legal
  183.  * (according to the Japanese Go Rules)
  184.  */
  185. GOGAME *gogame;
  186. PLACE    place;
  187. int    side;
  188. {
  189.     GONODE *n = NODE(gogame, place);
  190.  
  191. /*    #[RULES_OUTSIDE:    */
  192.  
  193.     if (0 > place || place >= gogame->gm_size * gogame->gm_size)
  194.     return RULES_OUTSIDE;
  195.  
  196. /*    #]RULES_OUTSIDE:    */ 
  197. /*    #[RULES_OCCUPIED:    */
  198.  
  199.     if (n->gn_stone != (GOMOVE *) 0) return RULES_OCCUPIED;
  200.     n->gn_stone = gogame->gm_movelast;
  201.  
  202. /*    #]RULES_OCCUPIED:    */ 
  203. /*    #[RULES_KO:        */
  204. /*    #]RULES_KO:        */ 
  205. /*    #[RULES_SUICIDE:    */
  206.  
  207.     /*
  208.      * First calculate the liberties of enemy chains (remove them if nessesary)
  209.      */
  210.     theside = (side == BLACK) ? WHITE : BLACK;
  211.     thelibs = 0;    goban_loop(gogame, n->gn_n, rules_liberty);
  212.     if (thelibs == 0)    goban_loop(gogame, n->gn_n, rules_remove);
  213.     thelibs = 0;    goban_loop(gogame, n->gn_e, rules_liberty);
  214.     if (thelibs == 0)    goban_loop(gogame, n->gn_e, rules_remove);
  215.     thelibs = 0;    goban_loop(gogame, n->gn_s, rules_liberty);
  216.     if (thelibs == 0)    goban_loop(gogame, n->gn_s, rules_remove);
  217.     thelibs = 0;    goban_loop(gogame, n->gn_w, rules_liberty);
  218.     if (thelibs == 0)    goban_loop(gogame, n->gn_w, rules_remove);
  219.  
  220.     /*
  221.      * Next calculate liberties of friendly chain
  222.      */
  223.     theside = side;
  224.     thelibs = 0;
  225.     goban_loop(gogame, n, rules_liberty);
  226.     if (thelibs == 0) return RULES_SUICIDE;
  227.  
  228. /*    #]RULES_SUICIDE:    */ 
  229.  
  230.     return RULES_LEGAL;
  231. }
  232.  
  233. /* #]rules_check:        */ 
  234.